﻿Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Workflow.ComponentModel

Namespace System.Workflow.Activities.Rules
    <Serializable> _
    Public NotInheritable Class RuleConditionCollection
        Inherits KeyedCollection([Of] String, RuleCondition)
        Implements IWorkflowChangeDiff
        ' Methods
        Public Sub Add(ByVal item As RuleCondition)
            If Me._runtimeInitialized Then
                Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
            End If
            If (item Is Nothing) Then
                Throw New ArgumentNullException("item")
            End If
            If (item.Name Is Nothing) Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, Messages.InvalidConditionName, New Object() { "item.Name" }))
            End If
            MyBase.Add(item)
        End Sub

        Public Function Diff(ByVal originalDefinition As Object, ByVal changedDefinition As Object) As IList([Of] WorkflowChangeAction)
            Dim list As New List([Of] WorkflowChangeAction)
            Dim conditions As RuleConditionCollection = DirectCast(originalDefinition, RuleConditionCollection)
            Dim conditions2 As RuleConditionCollection = DirectCast(changedDefinition, RuleConditionCollection)
            If (Not conditions2 Is Nothing) Then
                Dim condition As RuleCondition
                For Each condition In conditions2
                    If (Not conditions Is Nothing) Then
                        If conditions.Contains(condition.Name) Then
                            Dim conditionDefinition As RuleCondition = conditions.Item(condition.Name)
                            If Not conditionDefinition.Equals(condition) Then
                                list.Add(New UpdatedConditionAction(conditionDefinition, condition))
                            End If
                        Else
                            list.Add(New AddedConditionAction(condition))
                        End If
                        [Continue] For
                    End If
                    list.Add(New AddedConditionAction(condition))
                Next
            End If
            If (Not conditions Is Nothing) Then
                Dim condition3 As RuleCondition
                For Each condition3 In conditions
                    If (Not conditions2 Is Nothing) Then
                        If Not conditions2.Contains(condition3.Name) Then
                            list.Add(New RemovedConditionAction(condition3))
                        End If
                    Else
                        list.Add(New RemovedConditionAction(condition3))
                    End If
                Next
            End If
            Return list
        End Function

        Protected Overrides Function GetKeyForItem(ByVal item As RuleCondition) As String
            Return item.Name
        End Function

        Protected Overrides Sub InsertItem(ByVal index As Integer, ByVal item As RuleCondition)
            If Me._runtimeInitialized Then
                Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
            End If
            If (((Not item.Name Is Nothing) AndAlso (item.Name.Length >= 0)) AndAlso MyBase.Contains(item.Name)) Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, Messages.ConditionExists, New Object() { item.Name }))
            End If
            MyBase.InsertItem(index, item)
        End Sub

        Friend Sub OnRuntimeInitialized()
            SyncLock Me._runtimeInitializationLock
                If Not Me._runtimeInitialized Then
                    Dim condition As RuleCondition
                    For Each condition In Me
                        condition.OnRuntimeInitialized
                    Next
                    Me._runtimeInitialized = True
                End If
            End SyncLock
        End Sub

        Protected Overrides Sub RemoveItem(ByVal index As Integer)
            If Me._runtimeInitialized Then
                Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
            End If
            MyBase.RemoveItem(index)
        End Sub

        Protected Overrides Sub SetItem(ByVal index As Integer, ByVal item As RuleCondition)
            If Me._runtimeInitialized Then
                Throw New InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"))
            End If
            MyBase.SetItem(index, item)
        End Sub


        ' Properties
        Friend Property RuntimeMode As Boolean
            Get
                Return Me._runtimeInitialized
            End Get
            Set(ByVal value As Boolean)
                Me._runtimeInitialized = value
            End Set
        End Property


        ' Fields
        <NonSerialized> _
        Private _runtimeInitializationLock As Object = New Object
        Private _runtimeInitialized As Boolean
    End Class
End Namespace

